package com.boomshake.service.impl;

import com.boomshake.dto.RealNameRequest;
import com.boomshake.dto.UpdateUserRequest;
import com.boomshake.dto.WeChatLoginRequest;
import com.boomshake.entity.User;
import com.boomshake.mapper.UserMapper;
import com.boomshake.service.UserService;
import com.boomshake.utils.JwtUtil;
import com.boomshake.utils.WeChatUtil;
import com.boomshake.vo.LoginResponseVO;
import com.boomshake.vo.UserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.boomshake.common.PageResult;
import com.boomshake.dto.SetDistributorDTO;
import com.boomshake.dto.UserPageQueryDTO;
import com.boomshake.entity.DistributorRelation;
import com.boomshake.entity.Store;
import com.boomshake.mapper.DistributorRelationMapper;
import com.boomshake.mapper.StoreMapper;
import com.boomshake.vo.SetDistributorVO;
import com.boomshake.vo.UserPageVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

/**
 * 用户Service实现类
 *
 * @author BoomShake
 * @date 2024-12-15
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private WeChatUtil weChatUtil;

    @Autowired
    private DistributorRelationMapper distributorRelationMapper;
    
    @Autowired
    private StoreMapper storeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginResponseVO wechatLogin(WeChatLoginRequest request) {
        log.info("微信登录请求: {}", request.getCode());

        // 调用微信API获取用户信息
        WeChatUtil.WeChatLoginResult weChatResult = weChatUtil.getWeChatUserInfo(request.getCode());
        log.info("微信登录结果: {}", weChatResult);

        String openid = weChatResult.getOpenid();
        String unionid = weChatResult.getUnionid();

        // 查询用户是否已存在
        User user = getUserByOpenid(openid);
        
        if (user == null) {
            // 创建新用户
            user = createUser(openid, unionid);
            log.info("创建新用户: {}", user.getId());
        } else {
            // 更新最后登录时间
            userMapper.updateLastLoginTime(user.getId(), LocalDateTime.now());
            log.info("用户登录: {}", user.getId());
        }

        // 生成JWT token
        String token = jwtUtil.generateToken(user.getId(), openid);

        // 构建响应
        LoginResponseVO response = new LoginResponseVO();
        response.setToken(token);

        LoginResponseVO.UserInfo userInfo = new LoginResponseVO.UserInfo();
        userInfo.setId(user.getId());
        userInfo.setNickname(user.getNickname());
        userInfo.setAvatar(user.getAvatar());
        
        // 设置角色（暂时默认为普通用户）
        List<String> roles = new ArrayList<>();
        roles.add("CUSTOMER");
        userInfo.setRoles(roles);
        userInfo.setDistributor(false);
        
        response.setUserInfo(userInfo);

        return response;
    }

    @Override
    public UserInfoVO getUserInfo(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);

        // 设置角色（暂时默认为普通用户）
        List<String> roles = new ArrayList<>();
        roles.add("CUSTOMER");
        userInfoVO.setRoles(roles);

        // TODO: 如果是分销员，设置分销员信息
        
        return userInfoVO;
    }

    @Override
    public User getUserByOpenid(String openid) {
        return userMapper.selectByOpenid(openid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User createUser(String openid, String unionid) {
        User user = new User();
        user.setOpenid(openid);
        user.setUnionid(unionid);
        user.setCommissionBalance(BigDecimal.ZERO);
        user.setPoints(0);
        user.setRealNameStatus(0);
        user.setStatus(1);
        user.setLastLoginAt(LocalDateTime.now());

        userMapper.insert(user);
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserInfo(Long userId, User user) {
        user.setId(userId);
        return userMapper.updateById(user) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitRealNameAuth(Long userId, RealNameRequest request) {
        log.info("用户{}提交实名认证: 姓名={}, 身份证={}", userId, request.getRealName(), 
                request.getIdCard().replaceAll("(\\w{6})\\w*(\\w{4})", "$1****$2"));

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查用户是否已经实名认证
        if (user.getRealNameStatus() != null && user.getRealNameStatus() == 1) {
            throw new RuntimeException("用户已完成实名认证，无需重复认证");
        }

        // 更新实名信息
        User updateUser = new User();
        updateUser.setId(userId);
        updateUser.setRealName(request.getRealName());
        updateUser.setIdCard(request.getIdCard());
        updateUser.setRealNameStatus(1); // 设置为已认证

        boolean result = userMapper.updateById(updateUser) > 0;
        
        if (result) {
            log.info("用户{}实名认证成功", userId);
        } else {
            log.error("用户{}实名认证失败", userId);
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateProfile(Long userId, UpdateUserRequest request) {
        log.info("用户{}更新个人资料: {}", userId, request);

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 构建更新对象
        User updateUser = new User();
        updateUser.setId(userId);

        // 只更新非空字段
        if (StringUtils.hasText(request.getNickname())) {
            updateUser.setNickname(request.getNickname());
        }

        if (StringUtils.hasText(request.getAvatar())) {
            updateUser.setAvatar(request.getAvatar());
        }

        if (StringUtils.hasText(request.getPhone())) {
            updateUser.setPhone(request.getPhone());
        }

        if (request.getGender() != null) {
            updateUser.setGender(request.getGender());
        }

        if (request.getBirthday() != null) {
            updateUser.setBirthday(request.getBirthday());
        }

        boolean result = userMapper.updateById(updateUser) > 0;
        
        if (result) {
            log.info("用户{}个人资料更新成功", userId);
        } else {
            log.error("用户{}个人资料更新失败", userId);
        }
        
        return result;
    }

    @Override
    public PageResult<UserPageVO> getUserList(UserPageQueryDTO queryDTO) {
        log.info("查询用户列表，参数：{}", queryDTO);
        
        // 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 关键字搜索（昵称、手机号）
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            queryWrapper.like(User::getNickname, queryDTO.getKeyword())
                    .or()
                    .like(User::getPhone, queryDTO.getKeyword());
        }
        
        // 按实名状态筛选
        if (queryDTO.getRealNameStatus() != null) {
            queryWrapper.eq(User::getRealNameStatus, queryDTO.getRealNameStatus());
        }
        
        // 按用户状态筛选
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(User::getStatus, queryDTO.getStatus());
        }
        
        // 按照创建时间倒序
        queryWrapper.orderByDesc(User::getCreatedAt);
        
        // 执行分页查询
        Page<User> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        Page<User> pageResult;
        
        // 根据用户类型选择查询方式
        if (StringUtils.hasText(queryDTO.getUserType())) {
            if ("distributor".equals(queryDTO.getUserType())) {
                // 分销员查询可以使用关联表
                List<Long> distributorUserIds = distributorRelationMapper.selectUserIds();
                if (distributorUserIds == null || distributorUserIds.isEmpty()) {
                    // 没有分销员，返回空结果
                    return PageResult.empty(queryDTO);
                }
                queryWrapper.in(User::getId, distributorUserIds);
                pageResult = userMapper.selectPage(page, queryWrapper);
            } else if ("customer".equals(queryDTO.getUserType())) {
                // 普通用户查询（非分销员）
                List<Long> distributorUserIds = distributorRelationMapper.selectUserIds();
                if (distributorUserIds != null && !distributorUserIds.isEmpty()) {
                    queryWrapper.notIn(User::getId, distributorUserIds);
                }
                pageResult = userMapper.selectPage(page, queryWrapper);
            } else {
                pageResult = userMapper.selectPage(page, queryWrapper);
            }
        } else {
            pageResult = userMapper.selectPage(page, queryWrapper);
        }
        
        // 转换为VO
        List<UserPageVO> voList = new ArrayList<>();
        for (User user : pageResult.getRecords()) {
            voList.add(convertToUserPageVO(user));
        }
        
        return PageResult.of(voList, pageResult.getTotal(), queryDTO);
    }
    
    @Override
    public UserPageVO getUserDetail(Long userId) {
        log.info("查询用户详情，用户ID：{}", userId);
        
        // 查询用户基本信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        return convertToUserPageVO(user);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SetDistributorVO setDistributor(Long userId, SetDistributorDTO dto, Long operatorId) {
        log.info("设置用户为分销员，用户ID：{}，参数：{}", userId, dto);
        
        // 校验用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 校验门店是否存在
        Store store = storeMapper.selectById(dto.getStoreId());
        if (store == null) {
            throw new RuntimeException("门店不存在");
        }
        
        // 校验是否已经是分销员
        LambdaQueryWrapper<DistributorRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DistributorRelation::getUserId, userId);
        if (distributorRelationMapper.selectCount(queryWrapper) > 0) {
            throw new RuntimeException("该用户已经是分销员");
        }
        
        // 生成分销员编码
        String distributorCode = generateDistributorCode(dto.getStoreId());
        
        // 构建分销关系
        DistributorRelation relation = new DistributorRelation();
        relation.setUserId(userId);
        relation.setStoreId(dto.getStoreId());
        relation.setDistributorCode(distributorCode);
        relation.setLevel(dto.getLevel());
        relation.setStatus(1); // 默认激活
        relation.setActivatedAt(LocalDateTime.now());
        
        // 处理上下级关系
        if (dto.getParentDistributorId() != null) {
            // 查询上级分销员
            DistributorRelation parent = distributorRelationMapper.selectById(dto.getParentDistributorId());
            if (parent == null) {
                throw new RuntimeException("上级分销员不存在");
            }
            
            // 设置上级和根节点
            relation.setParentId(parent.getId());
            relation.setRootId(parent.getLevel() == 1 ? parent.getId() : parent.getRootId());
            relation.setDepth(parent.getDepth() + 1);
            
            // 处理左右值（简单实现，实际应该一次性调整所有节点）
            if (parent.getRightValue() != null) {
                relation.setLeftValue(parent.getRightValue());
                relation.setRightValue(parent.getRightValue() + 1);
                
                // 更新右值大于等于parent.rightValue的节点右值+2
                distributorRelationMapper.updateRightValues(parent.getRightValue());
            }
        } else {
            // 一级分销员
            if (dto.getLevel() != 1) {
                throw new RuntimeException("没有上级分销员时，等级必须为1");
            }
            
            relation.setParentId(null);
            relation.setRootId(null);
            relation.setDepth(0);
            
            // 初始左右值
            Integer maxRightValue = distributorRelationMapper.selectMaxRightValue();
            if (maxRightValue == null) {
                maxRightValue = 0;
            }
            relation.setLeftValue(maxRightValue + 1);
            relation.setRightValue(maxRightValue + 2);
        }
        
        // 保存分销关系
        distributorRelationMapper.insert(relation);
        
        // 构建返回结果
        SetDistributorVO vo = new SetDistributorVO();
        vo.setDistributorId(relation.getId());
        vo.setDistributorCode(relation.getDistributorCode());
        vo.setLevel(relation.getLevel());
        vo.setStoreId(relation.getStoreId());
        vo.setStoreName(store.getName());
        
        return vo;
    }
    
    /**
     * 将User实体转换为UserPageVO
     */
    private UserPageVO convertToUserPageVO(User user) {
        UserPageVO vo = new UserPageVO();
        BeanUtils.copyProperties(user, vo);
        
        // 设置用户角色
        List<String> roles = new ArrayList<>();
        roles.add("CUSTOMER");
        
        // 查询是否是分销员
        LambdaQueryWrapper<DistributorRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DistributorRelation::getUserId, user.getId());
        DistributorRelation relation = distributorRelationMapper.selectOne(queryWrapper);
        
        if (relation != null) {
            // 是分销员
            roles.add("DISTRIBUTOR");
            vo.setIsDistributor(true);
            
            // 设置分销员信息
            UserPageVO.DistributorInfo distributorInfo = new UserPageVO.DistributorInfo();
            distributorInfo.setDistributorId(relation.getId());
            distributorInfo.setDistributorCode(relation.getDistributorCode());
            distributorInfo.setLevel(relation.getLevel());
            distributorInfo.setStoreId(relation.getStoreId());
            distributorInfo.setStatus(relation.getStatus());
            
            // 获取门店名称
            if (relation.getStoreId() != null) {
                Store store = storeMapper.selectById(relation.getStoreId());
                if (store != null) {
                    distributorInfo.setStoreName(store.getName());
                }
            }
            
            // 获取上级分销员名称
            if (relation.getParentId() != null) {
                Map<String, Object> parentInfo = distributorRelationMapper.selectParentInfo(relation.getParentId());
                if (parentInfo != null) {
                    distributorInfo.setParentId(relation.getParentId());
                    distributorInfo.setParentName((String) parentInfo.get("nickname"));
                }
            }
            
            vo.setDistributorInfo(distributorInfo);
        } else {
            vo.setIsDistributor(false);
        }
        
        vo.setRoles(roles);
        return vo;
    }
    
    /**
     * 生成分销员编码
     */
    private String generateDistributorCode(Long storeId) {
        // 格式：D + 门店ID三位数 + 随机三位数 + 时间戳后四位
        String storeCode = String.format("%03d", storeId % 1000);
        String randomCode = String.format("%03d", new Random().nextInt(1000));
        String timeCode = String.format("%04d", System.currentTimeMillis() % 10000);
        
        return "D" + storeCode + randomCode + timeCode;
    }
} 